﻿using System;
using DataStructures.List;

namespace DataStructures.Test.List
{
    public abstract class TestList : Test
    {
        public static void testEmptyList(IList<String> list)
        {
            System.Console.Out.WriteLine("testEmptyList");

            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("0"), "false");
            try {
                list.pop();
            } catch (EmptyListException ex) {
                writeAssertion(ex.Message, "EmptyListException");
            }
            try {
                list.dequeue();
            } catch (EmptyListException ex) {
                writeAssertion(ex.Message, "EmptyListException");
            }
            try {
                list.getTop();
            } catch (EmptyListException ex) {
                writeAssertion(ex.Message, "EmptyListException");
            }
            try {
                list.getFirst();
            } catch (EmptyListException ex) {
                writeAssertion(ex.Message, "EmptyListException");
            }
            try {
                list.getLast();
            } catch (EmptyListException ex) {
                writeAssertion(ex.Message, "EmptyListException");
            }
            try {
                list.setFirst("0");
            } catch (EmptyListException ex) {
                writeAssertion(ex.Message, "EmptyListException");
            }
            try {
                list.setLast("0");
            } catch (EmptyListException ex) {
                writeAssertion(ex.Message, "EmptyListException");
            }
            try {
                list.removeFirst();
            } catch (EmptyListException ex) {
                writeAssertion(ex.Message, "EmptyListException");
            }
            try {
                list.removeLast();
            } catch (EmptyListException ex) {
                writeAssertion(ex.Message, "EmptyListException");
            }
            try {
                list.getByIndex(0);
            } catch (EmptyListException ex) {
                writeAssertion(ex.Message, "EmptyListException");
            }
            try {
                list.setByIndex(0, "0");
            } catch (EmptyListException ex) {
                writeAssertion(ex.Message, "EmptyListException");
            }
            try {
                list.removeByIndex(0);
            } catch (EmptyListException ex) {
                writeAssertion(ex.Message, "EmptyListException");
            }

            System.Console.Out.WriteLine();
        }
        public static void testOneElementBase(IList<String> list)
        {
            System.Console.Out.WriteLine("testOneElementBase");

            writeAssertion(list.addElement("0"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.indexOf("0"), "0");
            writeAssertion(list.indexOf("1"), "-1");
            writeAssertion(list.lastIndexOf("0"), "0");
            writeAssertion(list.lastIndexOf("1"), "-1");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "false");

            writeAssertion(list.getTop(), "0");
            writeAssertion(list.getFirst(), "0");
            writeAssertion(list.getLast(), "0");
            writeAssertion(list.removeElement("0"), "true");
            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("0"), "false");

            System.Console.Out.WriteLine();
        }
        public static void testOneElementStack(IList<String> list)
        {
            System.Console.Out.WriteLine("testOneElementBase");

            writeAssertion(list.push("0"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.indexOf("0"), "0");
            writeAssertion(list.indexOf("1"), "-1");
            writeAssertion(list.lastIndexOf("0"), "0");
            writeAssertion(list.lastIndexOf("1"), "-1");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "false");

            writeAssertion(list.getTop(), "0");
            writeAssertion(list.getFirst(), "0");
            writeAssertion(list.getLast(), "0");
            writeAssertion(list.pop(), "0");
            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("0"), "false");

            System.Console.Out.WriteLine();
        }
        public static void testOneElementQueue(IList<String> list)
        {
            System.Console.Out.WriteLine("testOneElementQueue");

            writeAssertion(list.enqueue("0"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.indexOf("0"), "0");
            writeAssertion(list.indexOf("1"), "-1");
            writeAssertion(list.lastIndexOf("0"), "0");
            writeAssertion(list.lastIndexOf("1"), "-1");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "false");

            writeAssertion(list.getTop(), "0");
            writeAssertion(list.getFirst(), "0");
            writeAssertion(list.getLast(), "0");
            writeAssertion(list.dequeue(), "0");
            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("0"), "false");

            System.Console.Out.WriteLine();
        }
        public static void testOneElement(IList<String> list)
        {
            System.Console.Out.WriteLine("testOneElement");
            testOneElementBase(list);
            testOneElementStack(list);
            testOneElementQueue(list);

            writeAssertion(list.insertBeforeFirst("0"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.indexOf("0"), "0");
            writeAssertion(list.indexOf("1"), "-1");
            writeAssertion(list.lastIndexOf("0"), "0");
            writeAssertion(list.lastIndexOf("1"), "-1");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "false");

            writeAssertion(list.getTop(), "0");
            writeAssertion(list.getFirst(), "0");
            writeAssertion(list.getLast(), "0");
            writeAssertion(list.removeFirst(), "0");
            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("0"), "false");

            writeAssertion(list.insertAfterLast("0"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.indexOf("0"), "0");
            writeAssertion(list.indexOf("1"), "-1");
            writeAssertion(list.lastIndexOf("0"), "0");
            writeAssertion(list.lastIndexOf("1"), "-1");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "false");

            writeAssertion(list.getTop(), "0");
            writeAssertion(list.getFirst(), "0");
            writeAssertion(list.getLast(), "0");
            writeAssertion(list.removeFirst(), "0");
            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("0"), "false");

            System.Console.Out.WriteLine();

            writeAssertion(list.insertByIndex(0, "0"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.indexOf("0"), "0");
            writeAssertion(list.indexOf("1"), "-1");
            writeAssertion(list.lastIndexOf("0"), "0");
            writeAssertion(list.lastIndexOf("1"), "-1");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "false");

            writeAssertion(list.getTop(), "0");
            writeAssertion(list.getFirst(), "0");
            writeAssertion(list.getLast(), "0");
            writeAssertion(list.removeByIndex(0), "0");
            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("0"), "false");

            System.Console.Out.WriteLine();
        }

        public static void testTwoElementsBase(IList<String> list)
        {
            System.Console.Out.WriteLine("testTwoElementsBase");

            writeAssertion(list.addElement("0"), "true");
            writeAssertion(list.addElement("1"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "2");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("2"), "false");

            writeAssertion(list.removeElement("0"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.hasElement("0"), "false");
            writeAssertion(list.hasElement("1"), "true");

            writeAssertion(list.addElement("2"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "2");
            writeAssertion(list.hasElement("2"), "true");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("0"), "false");

            writeAssertion(list.removeElement("2"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.hasElement("2"), "false");
            writeAssertion(list.hasElement("1"), "true");

            writeAssertion(list.removeElement("1"), "true");
            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("0"), "false");

            System.Console.Out.WriteLine();
        }
        public static void testTwoElementsStack(IList<String> list)
        {
            System.Console.Out.WriteLine("testTwoElementsStack");

            writeAssertion(list.push("0"), "true");
            writeAssertion(list.push("1"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "2");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("2"), "false");
            writeAssertion(list.getTop(), "1");

            writeAssertion(list.pop(), "1");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "false");

            writeAssertion(list.pop(), "0");
            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("0"), "false");

            System.Console.Out.WriteLine();
        }
        public static void testTwoElementsQueue(IList<String> list)
        {
            System.Console.Out.WriteLine("testTwoElementQueue");

            writeAssertion(list.enqueue("0"), "true");
            writeAssertion(list.enqueue("1"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "2");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("2"), "false");
            writeAssertion(list.getFirst(), "0");
            writeAssertion(list.getLast(), "1");

            writeAssertion(list.dequeue(), "0");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("0"), "false");

            writeAssertion(list.dequeue(), "1");
            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("1"), "false");

            System.Console.Out.WriteLine();
        }
        public static void testTwoElements(IList<String> list)
        {
            System.Console.Out.WriteLine("testTwoElement");
            testTwoElementsBase(list);
            testTwoElementsQueue(list);
            testTwoElementsStack(list);

            writeAssertion(list.insertBeforeFirst("1"), "true");
            writeAssertion(list.insertBeforeFirst("0"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "2");
            writeAssertion(list.indexOf("0"), "0");
            writeAssertion(list.indexOf("1"), "1");
            writeAssertion(list.indexOf("2"), "-1");
            writeAssertion(list.lastIndexOf("0"), "0");
            writeAssertion(list.lastIndexOf("1"), "1");
            writeAssertion(list.lastIndexOf("2"), "-1");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("2"), "false");
            writeAssertion(list.getFirst(), "0");
            writeAssertion(list.getLast(), "1");

            writeAssertion(list.removeFirst(), "0");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("0"), "false");

            writeAssertion(list.insertAfterLast("2"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "2");
            writeAssertion(list.indexOf("1"), "0");
            writeAssertion(list.indexOf("2"), "1");
            writeAssertion(list.indexOf("0"), "-1");
            writeAssertion(list.lastIndexOf("1"), "0");
            writeAssertion(list.lastIndexOf("2"), "1");
            writeAssertion(list.lastIndexOf("0"), "-1");
            writeAssertion(list.hasElement("2"), "true");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("0"), "false");
            writeAssertion(list.getFirst(), "1");
            writeAssertion(list.getLast(), "2");

            writeAssertion(list.removeLast(), "2");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("2"), "false");

            writeAssertion(list.removeLast(), "1");
            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("1"), "false");

            System.Console.Out.WriteLine();

            writeAssertion(list.insertAfterLast("1"), "true");
            writeAssertion(list.insertAfterLast("2"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "2");
            writeAssertion(list.indexOf("1"), "0");
            writeAssertion(list.indexOf("2"), "1");
            writeAssertion(list.indexOf("0"), "-1");
            writeAssertion(list.lastIndexOf("1"), "0");
            writeAssertion(list.lastIndexOf("2"), "1");
            writeAssertion(list.lastIndexOf("0"), "-1");
            writeAssertion(list.hasElement("2"), "true");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("0"), "false");
            writeAssertion(list.getFirst(), "1");
            writeAssertion(list.getLast(), "2");

            writeAssertion(list.removeLast(), "2");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("2"), "false");

            writeAssertion(list.insertBeforeFirst("0"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "2");
            writeAssertion(list.indexOf("0"), "0");
            writeAssertion(list.indexOf("1"), "1");
            writeAssertion(list.indexOf("2"), "-1");
            writeAssertion(list.lastIndexOf("0"), "0");
            writeAssertion(list.lastIndexOf("1"), "1");
            writeAssertion(list.lastIndexOf("2"), "-1");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("2"), "false");
            writeAssertion(list.getFirst(), "0");
            writeAssertion(list.getLast(), "1");

            writeAssertion(list.removeFirst(), "0");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("0"), "false");

            writeAssertion(list.removeFirst(), "1");
            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("1"), "false");

            System.Console.Out.WriteLine();

            writeAssertion(list.insertByIndex(0, "1"), "true");
            writeAssertion(list.insertByIndex(0, "0"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "2");
            writeAssertion(list.indexOf("0"), "0");
            writeAssertion(list.indexOf("1"), "1");
            writeAssertion(list.indexOf("2"), "-1");
            writeAssertion(list.lastIndexOf("0"), "0");
            writeAssertion(list.lastIndexOf("1"), "1");
            writeAssertion(list.lastIndexOf("2"), "-1");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("2"), "false");
            writeAssertion(list.getFirst(), "0");
            writeAssertion(list.getLast(), "1");

            writeAssertion(list.removeByIndex(0), "0");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("0"), "false");

            writeAssertion(list.insertByIndex(1, "2"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "2");
            writeAssertion(list.indexOf("1"), "0");
            writeAssertion(list.indexOf("2"), "1");
            writeAssertion(list.indexOf("0"), "-1");
            writeAssertion(list.lastIndexOf("1"), "0");
            writeAssertion(list.lastIndexOf("2"), "1");
            writeAssertion(list.lastIndexOf("0"), "-1");
            writeAssertion(list.hasElement("2"), "true");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("0"), "false");
            writeAssertion(list.getFirst(), "1");
            writeAssertion(list.getLast(), "2");

            writeAssertion(list.removeByIndex(1), "2");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("2"), "false");

            writeAssertion(list.removeByIndex(0), "1");
            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("1"), "false");

            System.Console.Out.WriteLine();

            writeAssertion(list.insertByIndex(0, "1"), "true");
            writeAssertion(list.insertByIndex(1, "2"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "2");
            writeAssertion(list.indexOf("1"), "0");
            writeAssertion(list.indexOf("2"), "1");
            writeAssertion(list.indexOf("0"), "-1");
            writeAssertion(list.lastIndexOf("1"), "0");
            writeAssertion(list.lastIndexOf("2"), "1");
            writeAssertion(list.lastIndexOf("0"), "-1");
            writeAssertion(list.hasElement("2"), "true");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("0"), "false");
            writeAssertion(list.getFirst(), "1");
            writeAssertion(list.getLast(), "2");

            writeAssertion(list.removeByIndex(1), "2");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("2"), "false");

            writeAssertion(list.insertByIndex(0, "0"), "true");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "2");
            writeAssertion(list.indexOf("0"), "0");
            writeAssertion(list.indexOf("1"), "1");
            writeAssertion(list.indexOf("2"), "-1");
            writeAssertion(list.lastIndexOf("0"), "0");
            writeAssertion(list.lastIndexOf("1"), "1");
            writeAssertion(list.lastIndexOf("2"), "-1");
            writeAssertion(list.hasElement("0"), "true");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("2"), "false");
            writeAssertion(list.getFirst(), "0");
            writeAssertion(list.getLast(), "1");

            writeAssertion(list.removeByIndex(0), "0");
            writeAssertion(list.isEmpty(), "false");
            writeAssertion(list.Size, "1");
            writeAssertion(list.hasElement("1"), "true");
            writeAssertion(list.hasElement("0"), "false");

            writeAssertion(list.removeByIndex(0), "1");
            writeAssertion(list.isEmpty(), "true");
            writeAssertion(list.Size, "0");
            writeAssertion(list.hasElement("1"), "false");

            System.Console.Out.WriteLine();
        }
    }
}
